#pragma once
#include "Optional.hpp"
#include <functional>

// Lazy<T> 类：实现延迟计算（惰性求值）的模板类
// T: 延迟计算的结果类型
template <typename T>
struct Lazy
{
    // 构造函数：接受一个函数和其参数
    // Func: 函数类型
    // Args: 函数参数包
    template <typename Func, typename... Args>
    Lazy(Func &&f, Args &&...args)
    {
        // 在构造时完美转发，但在 lambda 中使用值捕获
        m_func = [f = std::forward<Func>(f), 
                 args...] () mutable {  // 直接值捕获展开的参数包
            return f(args...);
        };
    }

    // Value 函数：获取计算结果
    // 如果是第一次调用，执行计算并缓存结果
    // 后续调用直接返回缓存的结果
    T &Value()
    {
        if (!m_value.isInit())
        {
            m_value = m_func();  // 首次访问时执行延迟计算
        }

        return *m_value;  // 返回计算结果的引用
    }

    // IsValueCreated：检查是否已经执行过计算
    // 返回值：true 表示已计算，false 表示尚未计算
    bool IsValueCreated() const
    {
        return m_value.isInit();
    }

private:
    std::function<T()> m_func;    // 存储待执行的函数及其参数
    Optional<T> m_value;          // 存储计算结果，使用 Optional 包装
};

// 辅助函数：用于创建 Lazy 对象的工厂函数
// 可以自动推导返回类型，使用更方便
// Func: 函数类型
// Args: 参数类型包
template <class Func, typename... Args>
Lazy<typename std::result_of<Func(Args...)>::type>
lazy(Func &&fun, Args &&...args)
{
    return Lazy<typename std::result_of<Func(Args...)>::type>(
        std::forward<Func>(fun), 
        std::forward<Args>(args)...
    );
}
